﻿using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using EPiServer.Core;
using EPiServer.PlugIn;
using EPiServer.Security;
using JetBrains.Annotations;
using log4net;
using log4net.Appender;

namespace OpenWaves.EPiServer.AdminTools.LogViewer
{
    [SuppressMessage("Microsoft.Design", "CA1053:StaticHolderTypesShouldNotHaveConstructors"), UsedImplicitly]
    [GuiPlugIn(Area = PlugInArea.AdminMenu, Url = Url, DisplayName = "Log viewer", LanguagePath = LanguagePath, RequiredAccess = AccessLevel.Administer)]
    public class LogViewerPlugin
    {
        private const string LanguagePath = "/openWaves/adminTools/logViewer";
        private const string Url = "~/App_Resource/OpenWaves.EPiServer/OpenWaves.EPiServer.AdminTools.LogViewer.UI.LogFileListing.aspx";

        public static string TranslateConfigurationFallback(string key, string fallback)
        {
            string langKey = string.Format(CultureInfo.InvariantCulture, 
                "{0}/{1}", LanguagePath, key);

            return LanguageManager.Instance.TranslateFallback(langKey, fallback);
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
        public static IEnumerable<LogDirectory> GetLogDirectories()
        {
            var configuration = ServiceLocator.Resolve<ILogViewerPluginConfiguration>();
            var configuredDirectories = configuration.LogDirectories;

            return configuredDirectories.Union(GetLog4NetDirectories())
                .Distinct(new NormalizedPathComparer())
                .Where(Directory.Exists)
                .Select(path => new LogDirectory(path))
                .ToList();

        }

        private static IEnumerable<string> GetLog4NetDirectories()
        {
            var logFiles = LogManager.GetCurrentLoggers()
                .SelectMany(log => log.Logger.Repository.GetAppenders())
                .OfType<FileAppender>()
                .Select(appender => appender.File)
                .Where(file => string.IsNullOrEmpty(file) == false)
                .ToList();

            return logFiles
                .Select(Path.GetDirectoryName)
                .Distinct(new NormalizedPathComparer())
                .ToList();
        }

    }
}